package io.jpress.module.article.flowable.listener;

import com.jfinal.aop.Inject;
import io.jpress.core.flowable.AutoLoadEventListener;
import io.jpress.module.article.model.Article;
import io.jpress.module.article.model.ArticleFlowStatus;
import io.jpress.module.article.service.ArticleFlowStatusService;
import io.jpress.module.article.service.ArticleService;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.engine.delegate.event.impl.FlowableProcessCancelledEventImpl;

import java.util.List;

/**
 * 监听流程下线，主要作用：把正在进行中的文章，全部设置为草稿状态
 * 当前任务被删除，比如 undeploy
 */
@AutoLoadEventListener(types = FlowableEngineEventType.PROCESS_CANCELLED)
public class ProcessCancelledListener implements FlowableEventListener {

    @Inject
    private ArticleFlowStatusService articleFlowStatusService;

    @Inject
    private ArticleService articleService;

    @Override
    public void onEvent(FlowableEvent event) {

        if (!(event instanceof FlowableProcessCancelledEventImpl)) {
            return;
        }


        FlowableProcessCancelledEventImpl e = (FlowableProcessCancelledEventImpl) event;

        ArticleFlowStatus flowStatus = articleFlowStatusService.findByProcessInstanceId(e.getProcessInstanceId());
        if (flowStatus != null) {

            flowStatus.setStatus(ArticleFlowStatus.STATUS_CANCEL_WITH_FINISHED);
            articleFlowStatusService.update(flowStatus);

            List<ArticleFlowStatus> flowStatuses = articleFlowStatusService.findListByArticleId(flowStatus.getArticleId());

            //所有流程均已完成，设置文章为草稿。
            //当前流程是被异常中断的
            if (isAllFinished(flowStatuses)) {
                Article article = articleService.findById(flowStatus.getArticleId());
                article.setStatus(Article.STATUS_DRAFT);
                articleService.update(article);
            }

        }

    }

    private boolean isAllFinished(List<ArticleFlowStatus> flowStatuses) {
        if (flowStatuses != null) {
            for (ArticleFlowStatus flowStatus : flowStatuses) {
                if (!flowStatus.isFinished()) {
                    return false;
                }
            }
        }
        return true;
    }


    @Override
    public boolean isFailOnException() {
        return false;
    }

    @Override
    public boolean isFireOnTransactionLifecycleEvent() {
        return false;
    }

    @Override
    public String getOnTransaction() {
        return null;
    }
}
